home *** CD-ROM | disk | FTP | other *** search
-
-
-
- DEGIF TURBO PASCAL UNIT DOCUMENTATION
-
-
-
- 1.0 INTRODUCTION
-
- DEGIF is a Turbo Pascal Unit to decode graphic images stored in
- CompuServe's Graphic Interchange Format (GIF). With this unit you can write
- your own GIF decoder or add GIF to any application. "GIF" and "Graphic
- Interchange Format" are trademarks of H & R Block, Inc. The GIF standard
- itself is in the public domain.
-
- This unit is fully documented but we will not release the source code
- at this time. This is a shareware product with a registration fee of $25
- payable to Cyborg Software Systems, Inc. 3119 Cossell Drive, Indianapolis,
- IN 46224. This unit, the documentation and the source and executable code
- for DEGIFER are all Copyright 1988 by Cyborg Software Systems, Inc.
-
- You may use this material for personal non-commercial use. If you like
- it we ask you to register it. If you distribute it for free you must
- distribute it in its original ARC form with all files intact. If you
- distribute it for a fee or if you wish to use DEGIF in any commercial
- application or custom programming written for fee or under contract, you
- must register it. Violation of the above terms infringes our copyright.
- Registered users will receive the next update free of charge. Further
- updates will cost registered users $5.
-
- Parts of this code are very loosely based on EXPANDER.INC by Bob Berry
- which was a Turbo Pascal 3.0 translation of EXPANDER.C written in C by Steve
- Wilhite. Sincere thanks and credit to them.
-
- 2.0 GIF DECODING
-
- The best way we know to document the DEGIF unit is to give an example
- program called DEGIFER. DEGIFER is a very, very primitive GIF display
- program for CGA graphics. It makes no attempts to match colors. It just
- plots points in (COLOR mod 4). On 2 color images its great. Most 16 color
- images are viewible. Beyond that you're on your own.
-
- You should print out a copy of DEGIFER.PAS and follow it along its main
- routine as we go.
-
- 2.1 Initialization
-
- The first thing you must do is pass a procedure pointer to your
- routines called GetByte and PutByte. GetByte must be a far-call function to
- retrieve one byte from the GIF file. PutByte must be a far-call procedure
- to put one pixel on the screen. We will discuss these routines in section
- 3.0 below. AddrGetByte and AddrPutByte are a global pointers declared in
- the DEGIF unit but you must initialize them.
-
- The next few lines of DEGIFER's main routine engage the CRT unit and
- prints the copyright notice. A file name is retrieved from the command line
- or the user is prompted for one. The file is opened. This is the file that
- GetByte gets its bytes from.
-
- The variables SkipIt, EOFin, Done, BufIndx and Count are initialized.
-
-
- Copyright (c) 1988 Cyborg Software Systems, Inc. page 1.
-
-
-
- DEGIF TURBO PASCAL UNIT DOCUMENTATION
-
-
- They are specific to this demo and your application may not need them.
-
- The DEGIF unit defines the following....
-
- Type MapType=(Global,Local);
-
- GIF files may or may not have a global color map and or a local color
- map for multiple image files. DEGIF needs its variable CurMap:MapType to be
- initialized before you begin.
-
-
- 2.2 Procedure GetGIFSig
-
- All valid GIF files begin with a 6 byte signature. The DEGIF unit
- provides a procedure GetGIFSig to retrieve it. After calling GetGIFSig the
- global string GIFSig should contain the string. As of this writing (March
- 1988) the only valid string is 'GIF87a'.
-
- 2.3 Procedure GetScrDes
-
- Following the GIF signature in a GIF file is the screen description.
- The DEGIF unit provides a procedure GetScrDes to retrieve it and initialize
- several global variables.
-
- ScreenWidth and ScreenHeight are type Word and contain the screen width
- and height in pixels. All images in this file will fit in this virtual
- screen space. Its up to you to scale, clip or scroll the image if it
- doesn't fit your physical screen. There is no information anywhere in
- current GIF files to help determine the proper aspect ratio. You have to
- just guess that in all likelihood screens of 320 x 200, 640 x 200, 320 x 400
- or 640 x 400 are really all supposed to be of the same aspect ratio. What
- you do with stuff like 640 x 350 or 640 x 480 on a screen that won't hold it
- is up to you.
-
- MapExists[Global] is a boolean that tells you if there is a global
- color map for this file.
-
- BitsOfColorPerPrimary is a Word but the only valid values are [1..8].
- I was just too lazy to declare it as a byte or sub-range type <heheh>. It
- is the topic of much debate among GIF developers as to how useful it is. It
- isn't necessary and my experience is it is unreliable. For EGA created
- images its value should be 2 because each primary color (red, green and
- blue) is designated by 2 bits. EGA's can therefore have 2^(2+2+2)=64
- possible colors. The GIF file might contain only 16 so
- BitsOfColorPerPrimary doesn't tell you how many you can display at once or
- how many colors are in this image.
-
- BitsPerPixel[Global] is a word that does tell you. You really don't
- need this value but we give it to you anyway. We provide also provide
- NumberOfColors[Global] which again is a word but it is in the range
- [1..256]. It is computed by...
-
- NumberOfColors[Global]:= (1 shl BitsPerPixel[Global]);
-
-
-
- Copyright (c) 1988 Cyborg Software Systems, Inc. page 2.
-
-
-
- DEGIF TURBO PASCAL UNIT DOCUMENTATION
-
-
- This means GIF color maps always contain 2, 4, 8, 16, 32, 64, 128 or
- 256 entries. The image may not actually contain that many colors. It may
- use fewer. I have no problem with 16 color images that contain only 10 or
- 12 colors. It really raises my dandruff when I download 256 color images
- with 31 colors!!! Editorial over.
-
- Some GIF files are composed of multiple small images that may overlap
- or may not fill the screen. The standard says you should first fill in a
- background before plotting the images. Some decoders don't bother. They
- leave the background black. DEGIF gives you BackgrColorIndex which tells
- you what color to paint the background.
-
- Next DEGIFER calls DisplayScrDes. This is its own routine which not
- only tells the user the information from the screen descriptor, it also
- attempts to correct aspect ratio by squeezing the image horizontally,
- smashing it vertically or clipping it if that doesn't work. You are
- responsible for coming up with such topological gymnastics and should feel
- free to do it however you want.
-
- 2.4 Procedure GetColorMap
-
- The GIF standard provides for an optional global color map. Most GIF
- files contain one. GetScrDes sets the boolean MapExists[Global] to true if
- there is a global map. The map is put in the following arrays....
-
- RedValue,GreenValue,BlueValue: array [0..255] of byte;
-
- Only values in the range [0..NumberOfColors[Global]-1] are defined.
- They are intensity values from [0..255] for the red, blue and green
- components of the color.
-
- After calling GetColorMap you must decide on a mapping method. This is
- the proverbial thing that "separates the men from the boys" when it comes to
- implementing GIF. DEGIFER does a total cop-out and ignores the map
- completely. It has the following statements...
-
- if MapExists[Global] then GetColorMap;
- DoMapping;
-
- ...but you'll probably want to implement it as...
-
- if MapExists[Global]
- then begin GetColorMap; DoMapping end
- else UseDefaultMap;
-
- The job of your DoMapping is to fill the array Color which is defined
- by the DEGIF unit as...
-
- Color: array [Global..Local,0..255] of byte;
-
- DoMapping should look like this...
-
-
- procedure DoMapping;
-
-
- Copyright (c) 1988 Cyborg Software Systems, Inc. page 3.
-
-
-
- DEGIF TURBO PASCAL UNIT DOCUMENTATION
-
-
- var I:integer;
- begin
- for I:=0 to NumberOfColors[CurMap]-1 do
- Color[CurMap,I]:= { Some function of }
- { RedValue[I], }
- { BlueValue[I] & }
- { GreenValue[I] }
- end;
-
- Here is a sample DoMapping that computes a least squares mapping for a
- 16 color mode on a PCjr or Tandy 1000...
-
- procedure DoMapping;
- const
- MyRed:array [0..15] of byte=
- (000,000,000,000, 170,170,170,170, 085,085,085,085, 255,255,255,255);
- MyGreen:array [0..15] of byte=
- (000,000,170,170, 000,000,170,170, 085,085,255,255, 085,085,255,255);
- MyBlue:array [0..15] of byte=
- (000,170,000,170, 000,170,000,170, 085,255,085,255, 085,255,085,255);
- var I,J,K:byte; D1,D2:real;
- begin
- for I:=0 to NumberOfColors[CurMap]-1 do
- begin
- D1:=9999.99; K:=0;
- for J:=0 to 15 do
- begin
- D2:= SQRT( (RedValue[I]-MyRed[J]) * (RedValue[I]-MyRed[J])+
- (GreenValue[I]-MyGreen[J]) * (GreenValue[I]-MyGreen[J])+
- (BlueValue[I]-MyBlue[J]) * (BlueValue[I]-MyBlue[J]) );
- if D2 < D1 then begin K:=J; D1:=D2 end
- end;
- Color[CurMap,I]:=K
- end
- end;
-
- 2.5 Reading blocks
-
- Its time now to get down to actual plotting! DEGIFER uses the GRAPH3
- procedure GraphColorMode to get into CGA's 320 x 200 x 4 color mode.
-
- The next thing to appear in a GIF file is a block. There are currently
- only two types. Image blocks are preceded by a comma. Extension blocks are
- preceded by an exclamation point. Any characters other than a ',' or '!'
- may be ignored. Keep reading until there is nothing left to read.
- Currently no extension blocks are defined. The DEGIF unit has a procedure
- that lets you skip extension blocks. It is cleverly called SkipExtendBlock.
-
- 2.6 Procedure GetImageDescription
-
- After finding an image block which begins with a comma you should call
- DEGIF's GetImageDescription procedure. It sets up the following global
- variables declared in DEGIF. Unless noted, all are type word.
-
-
-
- Copyright (c) 1988 Cyborg Software Systems, Inc. page 4.
-
-
-
- DEGIF TURBO PASCAL UNIT DOCUMENTATION
-
-
- ImageLeft and ImageTop define the coordinates of this image relative to
- the screen description. A value of 0,0 is the upper left corner of the
- screen.
-
- ImageWidth and ImageHeight give the dimensions of this image. The
- image may overlap previous images. It may or may not fill the screen. It
- should never exceed the screen description.
-
- MapExists[Local] is a boolean that tells you if a local color map
- exists for this image. If no local map exists then you should use the
- global map. Subsequent images never use old local maps. They always use
- their own local maps or they revert to the global map. The following code
- implements this properly.
-
- if MapExists[Local]
- then begin CurMap:=Local; GetColorMap; DoMapping end
- else CurMap:=Global;
-
- Note that GetColorMap and DoMapping depend on CurMap.
-
- The boolean variable Interlaced tells you how to plot the scan lines.
- See section 3.2 for a discussion of interlaced images.
-
- BitsPerPixel[Local] and NumberOfColors[Local] tell you the same things
- about the local map that their global brothers tell you about the global
- map.
-
- The AdjustImage routine is specific to DEGIFER and you may or may not
- need it.
-
- 2.7 Function ExpandGIF
-
- The data blocks which follow are the image data index values compressed
- in a variable length 12 bit-maximum modified LZW compression scheme.
-
- HUH?
-
- That's what I said when I first became a GIF developer. They just
- handed me a bunch of code written in "C" by Steve Wilhite. They said just
- use this code and everything will be ok. There was one problem. I don't
- know "C"! Enter Bob Berry who sees C and Pascal. My first GIF decoder used
- his Turbo Pascal 3.0 translation from Wilhite's "C". I plugged. It
- chugged. Out came GIF! Presto!
-
- Since then I've rewritten ExpandGIF several times on my own and I
- understand "image data index values compressed in a variable length 12 bit
- maximum modified LZW compression scheme."
-
- But you don't need to.
-
- ExpandGIF calls your GetByte routine to get compressed data one byte at
- a time. It does all the magic by calling your PutByte routine to put the
- dots on the screen.
-
-
-
- Copyright (c) 1988 Cyborg Software Systems, Inc. page 5.
-
-
-
- DEGIF TURBO PASCAL UNIT DOCUMENTATION
-
-
- When the entire image is done ExpandGIF returns an integer. Anything
- other than a 0 is an error.
-
- 3.0 ROUTINES YOU PROVIDE
-
- Routines like DoMapping and DisplayScreenDescription and AdjustImage
- are so totally your responsibility that we really can't say much more about
- them because you may want to do them differently. The GetByte and PutByte
- need more explanation.
-
- DO NOT FORGET TO INCLUDE THESE TWO LINES!
-
- AddrGetByte:=@GetByte;
- AddrPutByte:=@PutByte;
-
- 3.1 Function GetByte
-
- You must provide a function GetByte:Byte which returns sequential bytes
- from somewhere. It will most likely be a file but DEGIF could get its
- information from a modem to view GIF on-line. You'd need more information
- to do this than is provided here. (When I figure it out myself I'll have a
- new DEGIF uploaded.)
-
- This function must be a far function and is compiled with the {$F+}
- directive. The simplest GetByte is..
-
- {$F+}
- function GetByte:byte;
- var b:byte;
- begin
- Read(InFile,b);
- GetByte:=b
- end;
- {$F-}
-
- 3.2 Procedure PutByte(Pix:integer)
-
- PutByte isn't that simple. It passes you an integer in the range
- [0..255] that is the index to the Color array. PutByte should plot the
- color given by Color[CurMap,Pix] at location x,y. The catch is what are x
- and y?
-
- On non-interlaced images you just start at X:=ImageLeft and
- Y:=ImageTop. You plot points along Y and increment X until you've plotted
- ImageWidth of them. That is until X=ImageLeft+ImageWidth. Then you reset X
- to ImageLeft, increment Y and plot the next line.
-
- Interlaced images start with Y=ImageTop but they make 4 interlaced
- passes. Pass 1 begins at ImageTop+0 and plots every 8th line. Pass 2
- starts at ImageTop+4 and also plots every 8th line. Pass 3 starts at
- ImageTop+2 and plots every 4th line. Pass 4 starts at ImageTop+1 and plots
- every other line. These 4 passes fill the screen.
-
- In DEGIFER's PutByte routine I invented a Pass 5 which starts at
-
-
- Copyright (c) 1988 Cyborg Software Systems, Inc. page 6.
-
-
-
- DEGIF TURBO PASCAL UNIT DOCUMENTATION
-
-
- ImageTop+0 and plots every line. My procedure AdjustImage contains...
-
- if Interlaced then Pass:=1 else Pass:=5;
-
- This fully implements interlaced images.
-
- The PutByte routine must be compiled with the {$F+} far directive on.
-
- 4.0 INTERFACE
-
- Here is the interface section of the DEGIF unit.
-
-
- unit degif;
- interface
-
- type MapType=(Global,Local);
-
- var GIFSig:String[6]; {GIF ID string usually = 'GIF87a'}
- CurMap:MapType; {Current Map in use}
- BitsPerPixel, {in this image}
- NumberOfColors {in this image}
- :array [Global..Local] of word;
- BackgrColorIndex, {Background Color index}
- BitsOfColorPerPrimary, {For example on EGA=2}
- ImageLeft, {Left edge of image relative to virtual screen}
- ImageTop, {Top edge of image relative to virtual screen}
- ImageWidth, {in pixels}
- ImageHeight, {in pixels}
- ScreenHeight, {in pixels}
- ScreenWidth:word; {in pixels}
- MapExists:array [Global..Local] of boolean;
- Interlaced:boolean;
- AddrGetByte, {Pointer to user supplied GetByte}
- AddrPutByte:pointer; {Pointer to user supplied PutByte}
- RedValue,GreenValue,BlueValue: array [0..255] of byte;
- Color: array [Global..Local,0..255] of byte;
-
- function ExpandGif: integer;
-
- procedure GetColorMap;
-
- procedure GetGIFSig;
-
- procedure GetImageDescription;
-
- procedure GetScrDes;
-
- procedure SkipExtendBlock;
-
- 5.0 FINAL WORDS
-
- This unit is written entirely in Turbo Pascal 4.0 and contains no
- assembler or Inline code. My #1 goal was to get this available as soon as
-
-
- Copyright (c) 1988 Cyborg Software Systems, Inc. page 7.
-
-
-
- DEGIF TURBO PASCAL UNIT DOCUMENTATION
-
-
- possible. My #2 goal will be to make it fast. After that I'll add on-line
- viewing support and any new extensions to the GIF87a standard.
-
- To make it worth my trouble I need your support. Please show your
- appreciation and register this product.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (c) 1988 Cyborg Software Systems, Inc. page 8.